package whf.framework.entity;

import java.io.Serializable;
import java.sql.Timestamp;

import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.jdom.Element;

import whf.framework.exception.PropertyException;
import whf.framework.security.entity.Dept;
import whf.framework.security.entity.User;
import whf.framework.util.BeanUtils;
import whf.framework.web.struts.AbstractStrutsForm;
import whf.framework.xml.XmlUtils;

/**
 * 基本业务对象实体,实现了IBaseBO接口,使得对象拥有业务对象功能,
 * 继承了BaseForm表示业务对象本身可以作为ActionForm的表单
 * 实现了compareTo方法可以进行比较;
 * @author wanghaifeng
 * base entity
 */
@SuppressWarnings("unchecked")
public abstract class AbstractEntity extends AbstractStrutsForm implements Serializable, Entity{
	private final static long serialVersionUID = 0;
	
	private long id;
	
	private String code;
	
	private String name;
	
	private String remarks;
	
	private Timestamp createDate;
	
	private Timestamp updateDate;
	
	private boolean active;
	
	private User createBy;
	
	private User updateBy;

	private Dept dept; //the object belong to a org.
	
	/**
	 * for action form method name, not entity property
	 */
	
	public AbstractEntity(){
	}
	
	public AbstractEntity(AbstractEntity bo) throws PropertyException{
		this.cloneProperties(bo);
	}
	
	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#getId()
	 */
	public long getId(){
		return this.id;
	}
	
	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#setId(long)
	 */
	public void setId(long id){
		this.id = id;
	}
	
	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#getName()
	 */
	public String getName(){
		return this.name;
	}
	
	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#setName(java.lang.String)
	 */
	public void setName(String name){
		this.name=name;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#getRemarks()
	 */
	public String getRemarks() {
		return remarks;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#setRemarks(java.lang.String)
	 */
	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#getCreateDate()
	 */
	public Timestamp getCreateDate() {
		return createDate;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#setCreateDate(java.sql.Date)
	 */
	public void setCreateDate(Timestamp createDate) {
		this.createDate = createDate;
	}
	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#getLastUpdate()
	 */
	public Timestamp getUpdateDate() {
		return updateDate;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#setLastUpdate(java.sql.Date)
	 */
	public void setUpdateDate(Timestamp lastUpdate) {
		this.updateDate = lastUpdate;
	}

	public boolean isActive() {
		return active;
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#getCode()
	 */
	public String getCode() {
		return code;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#setCode(java.lang.String)
	 */
	public void setCode(String code) {
		this.code = code;
	}
	
	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#getCreateBy()
	 */
	public User getCreateBy() {
		return createBy;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#setCreateBy(org.framework.user.User)
	 */
	public void setCreateBy(User createBy) {
		this.createBy = createBy;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#getUpdateBy()
	 */
	public User getUpdateBy() {
		return updateBy;
	}

	/* (non-Javadoc)
	 * @see org.framework.entity.IBO#setUpdateBy(org.framework.user.User)
	 */
	public void setUpdateBy(User updateBy) {
		this.updateBy = updateBy;
	}

	/* (non-Javadoc)
	 * @see whf.framework.entity.IBaseBO#getDept()
	 */
	public Dept getDept() {
		return dept;
	}

	/* (non-Javadoc)
	 * @see whf.framework.entity.IBaseBO#setDept(whf.framework.auth.entity.Dept)
	 */
	public void setDept(Dept dept) {
		this.dept = dept;
	}

	/**
	 * @param obj
	 * @return
	 */
	public int compareTo(Object obj) {
		AbstractEntity bo = (AbstractEntity)obj;
		String name1 = this.getName();
		String name2 = bo.getName();
		name1 = name1 == null?"":name1;
		name2 = name2 == null? "": name2;
		return name1.compareTo(name2);
	}
	
	/* (non-Javadoc)
	 * @see whf.framework.entity.IBaseBO#cloneProperties(java.lang.Object)
	 */
	public void cloneProperties(Object source) throws PropertyException {
		BeanUtils.copyProperties(this, source);
	}

	/* (non-Javadoc)
	 * @see whf.framework.entity.IBaseBO#setProperty(java.lang.String, java.lang.Object)
	 */
	public void setProperty(String propertyName, Object value) throws PropertyException{
		BeanUtils.setProperty(this, propertyName, value);
	}
	
	/* (non-Javadoc)
	 * @see whf.framework.entity.IBaseBO#setProperty(java.lang.String, java.lang.Class, java.lang.String)
	 */
	public void setProperty(String propertyName, Class propertyType, String value) throws PropertyException{
		BeanUtils.setProperty(this, propertyType, propertyName, value);
	}
	
	/* (non-Javadoc)
	 * @see whf.framework.entity.IBaseBO#getProperty(java.lang.String)
	 */
	public Object getProperty(String propertyName) throws PropertyException{
		return BeanUtils.getProperty(this, propertyName);
	}

	/* (non-Javadoc)
	 * @see whf.framework.datasource.DataRow#getPropertyDisplay(java.lang.String)
	 */
	public String getPropertyDisplay(String propertyName)
			throws PropertyException {
		return BeanUtils.getSimpleProperty(this, propertyName);
	}

	/* (non-Javadoc)
	 * @see whf.framework.entity.IBaseBO#idEquals(whf.framework.entity.IBaseBO)
	 */
	public boolean idEquals(Entity bo) {
		if(bo == null) return false;
		if(this.getClass() != bo.getClass()) return false;
		return this.id == bo.getId();
	}

	/* (non-Javadoc)
	 * @see whf.framework.entity.IBaseBO#toDom()
	 */
	public Element toXmlElement() throws PropertyException {
		return XmlUtils.toXmlElement(this, null);
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		if(super.getClass() == AbstractEntity.class){
			sb.append(super.toString());
		}
		sb.append(ToStringBuilder.reflectionToString(this,ToStringStyle.MULTI_LINE_STYLE));
		return sb.toString();
	}

	@Override
	public int hashCode() {
		if(this.id == 0){
			return HashCodeBuilder.reflectionHashCode(this);
		} else {
			HashCodeBuilder hcb = new HashCodeBuilder();
			hcb.append(this.id);
			hcb.append(this.getClass().getName());
			return hcb.toHashCode();
		}
	}

	/* (non-Javadoc)
	 * @see whf.framework.datasource.DataRow#getDisplayName()
	 */
	public String getDisplayName() {
		if(this instanceof TreeNode) {
			TreeNode the = ((TreeNode)this);
			if(the.getParent() != null) {
				return the.getParent().getName() + " / " + this.name;
			} else {
				return this.name;
			}
		} else {
			return this.name;
		}
	}

	/* (non-Javadoc)
	 * @see whf.framework.datasource.DataRow#getPrimaryKey()
	 */
	public Serializable getPrimaryKey() {
		return this.id;
	}

}
